<?php


namespace app\api\service;


use app\api\model\Channel;
use app\api\model\ChannelBcard;
use app\api\model\ChannelCcard;
use app\api\model\Order;
use app\api\model\OrderBcard;
use app\api\model\OrderCcard;
use app\api\model\UserBcard;
use app\api\model\UserCcard;
use app\api\model\UserChannel;
use app\common\service\Order as OrderService;

class Bank
{
    private $channel_list;
    private $classNameSpace;
    public function __construct()
    {
        $this->channel_list = (Channel::getALL())->toArray();
        $this->classNameSpace = "\\app\\api\\service\\";
    }

    /**
     * 银行 商户进件 服务激活 及提现银行卡激活
     * @param array $data
     * @return bool
     * @throws \think\Exception
     */
    public function register(array $data){
        foreach ($this->channel_list as $k => $channel) {
            $classObject = $this->classNameSpace.$channel['classname'];
            $class = new $classObject();
            //判断当前用户对应渠道是否已注册激活
            if(UserChannel::checkUserChannel($data['user_id'],$channel['channel_id'])){
                continue;
            }
            $res = $class->register($data);
            //写入user_channel表
            $data['rate'] = $channel['rate'];
            $data['advancefee'] = $channel['advancefee'];
            $userchannel_id = $this->writeUserChannel($data,$channel['channel_id']);
            $userchannelmodel = new UserChannel();
            $updtadata = [];
            if($res['code'] == 1){
                //注册成功
                $updtadata['merchantno'] = $res['merchantno'];
                $updtadata['notes'] = $res['msg'];
                $updtadata['status'] = 1;
            }else{
                //注册失败
                throw new \think\Exception("渠道".$channel['channel_id']."-用户注册失败:".$res['msg'], 0);
            }
            $userchannelmodel->where('id', $userchannel_id)
                ->update($updtadata);

            //激活服务
            $data_op = [];
            $data_op['merchantno'] = $res['merchantno'];
            $data_op['rate'] = $channel['rate']*0.01;
            $data_op['fee'] = $channel['advancefee'];
            $opening_res = $class->opening($data_op);
            $opening_updtadata = [];
            if($opening_res['code'] == 1){
                $opening_updtadata['opening'] = 1;
            }else{
                throw new \think\Exception("渠道".$channel['channel_id']."-用户注册失败:".$res['msg'], 0);
            }
            $userchannelmodel->where('id', $userchannel_id)
                ->update($opening_updtadata);
            //判断银行卡是否绑定过
            if(UserBcard::check($data['user_id'],$data['acctid'])){
                //未绑定则进行绑定绑定银行卡
                if (!$bcard_id = UserBcard::insertData($data)){
                    throw new \think\Exception("用户注册失败:银行卡绑定失败", 0);
                }
            }
            //渠道银行卡激活
            if(!ChannelBcard::insertData($bcard_id,$channel['channel_id'],$class->bcardneedotifiy)){
                throw new \think\Exception("用户注册失败:银行卡激活失败 | 渠道:".$channel['channel_id'], 0);
            }
        }
        return true;
    }

    /**写入user_channel表
     * @param $data
     * @param $channel_id
     * @return bool|mixed
     */
    public function writeUserChannel($data,$channel_id){
        $data['channel_id'] = $channel_id;
        $model = new UserChannel();
        return $model->insertData($data);
    }

    /**
     * 修改用户结算卡
     * @param array $data
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function changeBcard(array $data){
        foreach ($this->channel_list as $k => $channel) {
            $classObject = $this->classNameSpace.$channel['classname'];
            $class = new $classObject();
            $chbmodel = ChannelBcard::where(['bcard_id'=>$data['user_bcard_id'],'channel_id'=>$channel['channel_id']])->find();
            if(!$chbmodel){
                throw new \think\Exception("银行卡修改失败 | 渠道:".$channel['channel_id']."没有对应数据", 0);
            }
            //查询用户渠道相关商户号
            $ucmodel = UserChannel::where(['user_id'=>$data['user_id'],'channel_id'=>$channel['channel_id'],'status'=>1,'opening'=>1])->find();
            if(!$ucmodel){
                throw new \think\Exception("银行卡修改失败 | 渠道:".$channel['channel_id']."没有激活", 0);
            }
            $data['merchantno'] = $ucmodel->merchantno;
            //调用对应渠道 修改银行卡 的接口
            $res = $class->changeBcard($data);
            if ($res['code'] != 1){
                throw new \think\Exception("银行卡修改失败 | 渠道:".$channel['channel_id'], 0);
            }else{
                //修改对应的数据
                $new_data = [
                    'orderno' =>OrderService::createOrderNo(),
                    'notes' => "激活成功111",
                    'status' => 1,
                ];
                if (!$chbmodel->save($new_data)){
                    throw new \think\Exception("银行卡修改失败 | 渠道:".$channel['channel_id'], 0);
                }
            }
        }
        return true;
    }

    /**
     * 绑定消费银行卡
     * @param $data
     */
    public function bindcard($data){
        foreach ($this->channel_list as $k => $channel) {
            $classObject = $this->classNameSpace.$channel['classname'];
            //查询用户渠道相关商户号
            $ucmodel = UserChannel::where(['user_id'=>$data['user_id'],'channel_id'=>$channel['channel_id'],'status'=>1,'opening'=>1])->find();
            if(!$ucmodel){
                throw new \think\Exception("银行卡修改失败 | 渠道:".$channel['channel_id']."没有激活", 0);
            }
            $data['merchantno'] = $ucmodel->merchantno;
            $class = new $classObject();
            $data['orderNo'] = OrderService::createOrderNo();
            $res = $class->bindCcard($data);
            if ($res['code'] != 1){
                throw new \think\Exception("绑定银行卡失败 | 渠道:".$channel['channel_id'], 0);
            }else{
                $save_channelccard = [
                    'orderno' => $data['orderNo'],
                    'ccard_id' => $data['ccard_id'],
                    'channel_id' => $channel['channel_id'],
                    'notes' => $class->bcardneedotifiy?$res['msg']:'激活成功',
                    'status' => $class->bcardneedotifiy?0:1,
                    'wxapp_id' => $data['wxapp_id']
                ];
                $ccmodel = new ChannelCcard();
                if(!$ccmodel->save($save_channelccard)){
                    throw new \think\Exception("绑定银行卡失败 | 渠道:".$channel['channel_id']."激活失败", 0);
                }
            }
        }
        return true;
    }

    /**
     * 解绑消费银行卡
     * @param $data
     */
    public function unbindcard($data){
        foreach ($this->channel_list as $k => $channel) {
            //查询用户渠道相关商户号
            $ucmodel = UserChannel::where(['user_id'=>$data['user_id'],'channel_id'=>$channel['channel_id'],'status'=>1,'opening'=>1])->find();
            if(!$ucmodel){
                throw new \think\Exception("银行卡修改失败 | 渠道:".$channel['channel_id']."没有激活", 0);
            }
            $data['merchantno'] = $ucmodel->merchantno;
            //查找对应的银行卡号
            $classObject = $this->classNameSpace.$channel['classname'];
            $class = new $classObject();
            $res = $class->unbindCcard($data);
            if ($res['code'] != 1){
                throw new \think\Exception("解绑银行卡失败 | 渠道:".$channel['channel_id'], 0);
            }else{
                ChannelCcard::where(['ccard_id'=>$data['ccard_id'],'channel_id'=>$channel['channel_id']])->delete();
            }
        }
        return true;
    }

    /**
     * 修改费率
     * @param array $data
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function changerate(array $data){
        $type = $data['type'];//all 双通道  big 大额  small小额  appoint 指定
        foreach ($this->channel_list as $k => $channel) {
            //
            if ($type == 1 && $data['channel_id'] != $channel['channel_id']){
                continue;
            }else if ($type == 10 && $data['type'] != $channel['type']){
                continue;

            }else if ($type == 20 && $data['type'] != $channel['type']){
                continue;
            }
            //根据用户及渠道查找对应记录
            $ucmodel = UserChannel::where(['user_id'=>$data['user_id'],'channel_id'=>$channel['channel_id'],'status'=>1,'opening'=>1])->find();
            if(!$ucmodel){
                throw new \think\Exception("费率修改失败 | 渠道:".$channel['channel_id']."没有激活", 0);
            }
            $data['merchantno'] = $ucmodel->merchantno;
            $classObject = $this->classNameSpace.$channel['classname'];
            $class = new $classObject();
            $res = $class->changeRate($data);
            if ($res['code'] != 1){
                throw new \think\Exception("费率修改失败 | 渠道:".$channel['channel_id'], 0);
            }else{
                //修改对应用户渠道费率及手续费
                $save_data = [
                   'rate' => $data['rate'],
                   'advancefee' =>  $data['fee'],
                ];
                if (!$ucmodel->save($save_data)){
                    throw new \think\Exception("费率修改失败 | 渠道:".$channel['channel_id'], 0);
                }
            }
        }
        return true;
    }

    /**
     * 提交交易
     * @param array $data
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function pay(array $data){
        //选择渠道
        $channel_chioce = [];
        foreach ($this->channel_list as $k => $channel) {
            if($channel['type'] == $data['type']){
                $channel_chioce[] = $channel;
            }
        }
        $channel = self::choicechannel($channel_chioce);
        //根据用户及渠道查找对应记录
        $ucmodel = UserChannel::where(['user_id'=>$data['user_id'],'channel_id'=>$channel['channel_id'],'status'=>1,'opening'=>1])->find();
        if(!$ucmodel){
            throw new \think\Exception("交易提交失败 | 渠道:".$channel['channel_id'], 0);
        }
        $ucard = UserCcard::where(['ccard_id'=>$data['ccard_id'],'status'=>1])->find();
        if(!$ucard){
            throw new \think\Exception("交易提交失败 | 找不到对应信用卡", 0);
        }
        //读取支付信用卡信息
        $data['merchantno'] = $ucmodel->merchantno;
        $data['rate'] = $ucmodel->rate;
        $data['advancefee'] = $ucmodel->advancefee;
        $data['realname'] = $ucard->realname;
        $data['bankname'] = $ucard->bankname;
        $data['certno'] = $ucard->certno;
        $data['accno'] = $ucard->accno;
        $data['phoneno'] = $ucard->phoneno;
        $data['cvv2'] = $ucard->cvv2;
        $data['validity'] = $ucard->validity;
        $data['wxapp_id'] = $ucard->wxapp_id;
        $classObject = $this->classNameSpace.$channel['classname'];
        $class = new $classObject();
        $res = $class->pay($data);
        if ($res['code'] != 1){
            throw new \think\Exception("交易提交失败 | 渠道:".$channel['channel_id'], 0);
        }else{
            //将数据写入 订单相关的yoshop_order_ccard表中
            $data_i_orderccard = [
                'order_id'=>$data['order_id'],
                'ccard_id'=>$data['ccard_id'],
                'totle_money'=>$data['totle_money'],
                'bankname'=>$data['bankname'],
                'realname'=>$data['realname'],
                'accno'=>$data['accno'],
                'phoneno'=>$data['phoneno'],
                'province'=>$data['province'],
                'city'=>$data['city'],
                'rate'=>$data['rate'],
                'advancefee'=>$data['advancefee'],
                'wxapp_id'=>$data['wxapp_id']
            ];
            $oc = new OrderCcard();
            $oc->save($data_i_orderccard);
            return $channel['channel_id'];
        }
    }

    /**
     * 选择渠道
     * @param $channel_array
     * @return mixed
     */
    private function choicechannel($channel_array){
        //获取符合渠道的数量
        $array_num = count($channel_array);
        return $array_num==1?$channel_array[0]:$channel_array[rand(0,$array_num)];
    }

    public function cash($order_no){

        $order = Order::get(['order_no'=>$order_no]);

        //选择渠道
        $channel_select = [];
        foreach ($this->channel_list as $k => $channel) {
            if($channel['channel_id'] == $order['channel_id']){
                $channel_select = $channel;
                break;
            }
        }
        $channel = $channel_select;

        //根据用户及渠道查找对应记录
        $ucmodel = UserChannel::where(['user_id'=>$order['user_id'],'channel_id'=>$channel['channel_id'],'status'=>1,'opening'=>1])->find();
        if(!$ucmodel){
            throw new \think\Exception("提现提交失败 | 渠道:".$channel['channel_id'], 0);
        }
        $ubmodel = UserBcard::where(['user_id'=>$order['user_id'],'status'=>1])->find();
        $data['merchantno'] = $ucmodel->merchantno;
        $data['order_no'] = $order['order_no'];
        $data['order_price'] = $order['order_price'];
        $data['advancefee'] = $ucmodel->advancefee;
        $data['accno'] = $ubmodel->accno;
        $data['bankname'] = $ubmodel->bankname;
        $data['realname'] = $ucmodel->realname;
        $data['certno'] = $ucmodel->certno;
        $classObject = $this->classNameSpace.$channel['classname'];
        $class = new $classObject();
        $res = $class->cash($data);
        if ($res['code'] != 1){
            throw new \think\Exception("提现提交失败 | 渠道:".$channel['channel_id'], 0);
        }else{
            $order_id = $order['order_id'];
            //变更发货状态
            Order::updateToDelivery($order_id);
            //将数据写入 订单相关的yoshop_order_bcard表中
            $data_i_orderbcard = [
                'order_id'=>$order_id,
                'bcard_id'=>$ubmodel['bcard_id'],
                'totle_money'=>$order['order_price'],
                'bankname'=>$ubmodel->bankname,
                'realname'=>$ucmodel->realname,
                'accno'=>$ubmodel->accno,
                'phoneno'=>$ucmodel->phoneno,
                //'province'=>"",
                //'city'=>"",
                'rate'=>$ucmodel->rate,
                'advancefee'=>$ucmodel->advancefee,
                'wxapp_id'=>$order['wxapp_id']
            ];
            $ob = new OrderBcard();
            $ob->save($data_i_orderbcard);
            $model = Order::getOrderDetailByOrderNo($order_no);
            $model->receipt();
            return true;
        }


    }
}